#include <QtTest>
#include <QSignalSpy>

#include "test_ShowManager.h"
#include "ShowManager.h"
#include "ShowFactoryForTest.h"
#include "MockScriptEngine.h"
#include "MediaListModel.h"
#include "MockMediaSourceFactory.h"
#include "lightpresetmodel.h"
#include "SequenceModel.h"
#include "LightPresetFactory.h"
#include "ApplicationSettings.h"

#define DMX_CHANNELS_FOR_TEST  10


test_ShowManager::test_ShowManager()
{

}

/** executed before every test case */
void test_ShowManager::init()
{
   m_showFactory = new ShowFactoryForTest( DMX_CHANNELS_FOR_TEST, this);
   m_notificationLog = new QStringList();
   m_showFactory->setNotificationLog( m_notificationLog);
   m_scriptEngine = new MockScriptEngine();
   MockMediaSourceFactory *mediaFactory = new MockMediaSourceFactory();
   m_mediaModel = new MediaListModel( mediaFactory, this);
   LightPresetFactory *lightFactory = new LightPresetFactory( this);
   m_lightModel = new LightPresetModel( DMX_CHANNELS_FOR_TEST, lightFactory, this);
   m_sequenceItemList = new QList<SequenceItem *>();
   m_sequenceModel = new SequenceModel( *m_sequenceItemList, this);
   m_showManager = new ShowManager( m_showFactory, *m_scriptEngine, *m_mediaModel,
                                    *m_lightModel, *m_sequenceModel, this);
}

/** executed after every test case */
void test_ShowManager::cleanup()
{
   delete m_showManager;
   delete m_sequenceModel;
   delete m_sequenceItemList;
   delete m_lightModel;
   delete m_mediaModel;
   delete m_scriptEngine;
   delete m_notificationLog;
   delete m_showFactory;
}

void test_ShowManager::initTestCase()
{
}

void test_ShowManager::cleanupTestCase()
{
}

void test_ShowManager::testInstance()
{
   QVERIFY( m_showManager != NULL);
}

void test_ShowManager::testLoadShow()
{
   QSignalSpy spyNewSearchPath( m_showManager, SIGNAL(newSearchPath(QString)));
   QSignalSpy spyScriptContent( m_showManager, SIGNAL(scriptContent(QString)));
   QSignalSpy spyShowNameChanged( m_showManager, SIGNAL(showNameChanged(QString)));

   m_showManager->loadShowFile( QString(PROJECT_PATH) + "ShowFileParser/test/BigFinalTest.mts");

   QCOMPARE( spyNewSearchPath.length(), 1);
   QString newSearchPath = spyNewSearchPath.at(0).at(0).toString();
   QVERIFY2( newSearchPath.endsWith("ShowFileParser/test"), newSearchPath.toLatin1());

   QCOMPARE( spyScriptContent.length(), 1);
   QCOMPARE( spyShowNameChanged.length(), 1);
   QString showName = spyShowNameChanged.at(0).at(0).toString();
   QVERIFY2( showName.endsWith("BigFinalTest.mts"), showName.toLatin1());
}

void test_ShowManager::testLoadingChangesApplicationSettings()
{
   ApplicationSettings::setLastShowFile("c:/Fake/Path.mts");

   m_showManager->loadShowFile( QString(PROJECT_PATH) + "ShowFileParser/test/BigFinalTest.mts");

   QVERIFY2( ApplicationSettings::lastShowFile().contains("BigFinalTest.mts"),
             ApplicationSettings::lastShowFile().toLatin1());
}

void test_ShowManager::testNotificationOnInvalidFile()
{
   m_showManager->loadShowFile("C:/Fake/Path/Show.mp3");

   QCOMPARE( m_notificationLog->length(), 2);
   QCOMPARE( m_notificationLog->at(0), QString("Error during file loading:")); /* title */
   QCOMPARE( m_notificationLog->at(1), QString("file C:/Fake/Path/Show.mp3 does not exist")); /* body */
}

void test_ShowManager::testSaveShowAs()
{
   QSignalSpy spyShowSaved( m_showManager, SIGNAL(showSaved(QString)));
   /* suppose user will choose this name by GUI */
   m_showFactory->setUserSelectedFilePath("C:/testSaveShowAs/mocked/Path.mts");

   m_showManager->onSaveShowAsRequest();

   QCOMPARE( ApplicationSettings::lastShowFile(), QString("C:/testSaveShowAs/mocked/Path.mts"));
   QCOMPARE( spyShowSaved.length(), 1);
   QCOMPARE( spyShowSaved.at(0).at(0).toString(), QString("C:/testSaveShowAs/mocked/Path.mts"));
}

void test_ShowManager::testSaveShowAgain()
{
   QSignalSpy spyShowSaved( m_showManager, SIGNAL(showSaved(QString)));
   /* suppose user will choose this name by GUI */
   m_showFactory->setUserSelectedFilePath("C:/testSaveShow/FirstName.mts");

   m_showManager->onSaveShowAsRequest();

   /* this name must not be used */
   m_showFactory->setUserSelectedFilePath("C:/testSaveShow/AnotherName.mts");
   m_showManager->onSaveShowRequest();

   QCOMPARE( ApplicationSettings::lastShowFile(), QString("C:/testSaveShow/FirstName.mts"));
   QCOMPARE( spyShowSaved.length(), 2);
   QString nameOnSecondSave = spyShowSaved.at(1).at(0).toString();
   QCOMPARE( nameOnSecondSave, QString("C:/testSaveShow/FirstName.mts"));
}

void test_ShowManager::testSaveShowAfterLoad()
{
   QSignalSpy spyShowSaved( m_showManager, SIGNAL(showSaved(QString)));

   m_showManager->loadShowFile( QString(PROJECT_PATH) + "ShowFileParser/test/BigFinalTest.mts");

   m_showFactory->setUserSelectedFilePath("C:/testSaveShowAfterLoad/Should/not/be/used.mts");
   m_showManager->onSaveShowRequest();

   QCOMPARE( spyShowSaved.count(), 1);
   QString nameOnSave = spyShowSaved.at(0).at(0).toString();
   QVERIFY2( nameOnSave.contains( "BigFinalTest.mts"), nameOnSave.toLatin1());
}
